package com.google.code.sms.io;

import java.io.IOException;
import java.io.InputStream;

import com.google.code.sms.Logger;
import com.google.code.sms.domain.MediaElement;
import com.google.code.sms.domain.PlayQueue;
import com.google.code.sms.domain.Player;
import com.google.code.sms.domain.TransferStatus;
import com.google.code.sms.service.MediaElementService;
import com.google.code.sms.service.TranscodingService;
import com.google.code.sms.util.FileUtil;

/**
 *
 * @author Scott Ware
 */
public class PlayQueueInputStream extends InputStream
{
    private static final Logger LOG = Logger.getLogger("PlayQueueInputStream");
    
    private final Player player;
    private final TransferStatus status;
    private final TranscodingService.Parameters parameters;
    private final TranscodingService transcodingService;
    private final MediaElementService mediaElementService;
    private MediaElement currentMediaElement;
    private InputStream currentInputStream;

    public PlayQueueInputStream(Player player, TransferStatus status, TranscodingService.Parameters parameters, TranscodingService transcodingService,
            MediaElementService mediaElementService)
    {
        this.player = player;
        this.status = status;
        this.parameters = parameters;
        this.transcodingService = transcodingService;
        this.mediaElementService = mediaElementService;
    }

    @Override
    public int read() throws IOException
    {
        byte[] b = new byte[1];
        int n = read(b);
        return n == -1 ? -1 : b[0];
    }

    @Override
    public int read(byte[] b) throws IOException
    {
        return read(b, 0, b.length);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException
    {
        prepare();
        
        if (currentInputStream == null)
        {
            return -1;
        }

        int n = currentInputStream.read(b, off, len);

        if(n != -1)
        {
            status.addBytesTransfered(n);
        }

        return n;
    }

    private void prepare() throws IOException
    {
        MediaElement element = parameters.getMediaElement();
        
        if (element == null)
        {
            close();
        }
        else if (!element.equals(currentMediaElement))
        {
            close();
            LOG.info(player.getUsername() + " listening to \"" + FileUtil.getShortPath(element.getFile()) + "\"");
            mediaElementService.incrementPlayCount(element);

            currentInputStream = transcodingService.getTranscodedInputStream(parameters);
            currentMediaElement = element;
            status.setFile(currentMediaElement.getFile());
        }
    }

    @Override
    public void close() throws IOException
    {
        try
        {
            if (currentInputStream != null)
            {
                currentInputStream.close();
            }
        }
        finally
        {
            currentInputStream = null;
            currentMediaElement = null;
        }
    }
}
